# 优先导入内置模块，其次是第三方模块，最后是自定义模块
from random import randint

from django.conf import settings
from django.http import JsonResponse
from django_redis import get_redis_connection
from django.shortcuts import render, redirect, HttpResponse

from web import models
from utils.response import BaseResponse
from web.forms.account import LoginForm, SmsLoginForm, MobileForm


class Role(object):
    ADMIN = '1'
    CUSTOMER = '2'


def logout(request):
    """注销"""
    request.session.clear()
    return redirect(settings.LOGIN_URL)


def login(request):
    # GET 显示登录页面
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'login.html', {'form': form})

    # POST 接收用户的数据并校验
    # print(request.POST)
    # 1. 接收用户的数据并进行数据格式的校验
    # 1.1 利用forms校验成功进行下一步
    form = LoginForm(data=request.POST)
    # 这里执行form.is_valid后会依次执行clean_fields()：对每个字段进行单独验证，确保字段值符合定义的规则，其中对password已加密的字段，不需要再次加密。
    # 调用_clean_form()：对整个表单进行验证，处理表单级别的验证逻辑。
    # 调用_post_clean())：在所有字段和表单级别的验证完成后，执行一些清理工作，例如设置表单实例的属性。
    if not form.is_valid():
        # 失败保留之前输入的数据
        return render(request, 'login.html', {'form': form})
    # {'role': '1', 'username': 'root', 'password': '9742981d160beffce6b33dd6b6d40d77'} <class 'dict'>
    data_dict = form.cleaned_data
    role = data_dict.pop('role')
    # 这里执行form.is_valid后会依次执行clean_fields()：对每个字段进行单独验证，确保字段值符合定义的规则，其中对password已加密的字段，不需要再次加密。
    # password = md5(password)

    # 2. 去数据库进行校验
    if role == Role.ADMIN:
        # 在filter加入active是为了判断是否以删除改用户
        user_project = models.Administrator.objects.filter(active=1).filter(**data_dict).first()
    else:
        user_project = models.Customer.objects.filter(active=1).filter(**data_dict).first()
    # 2.1 验证失败
    if not user_project:
        form.add_error('password', '用户名或密码错误')
        return render(request, 'login.html', {'form': form})

    # 2.2 验证成功，将用户信息写入session中，进入项目后台
    mapping = {'1': 'ADMIN', '2': 'CUSTOMER'}
    request.session[settings.NB_SESSION_KEY] = {'role': mapping[role], 'username': user_project.username,
                                                'id': user_project.id}

    return redirect(settings.LOGIN_HOME)


def sms_login(request):
    res = BaseResponse()
    if request.method == 'GET':
        form = SmsLoginForm()
        return render(request, 'sms_login.html', {'form': form})

    # 1. 对手机格式的校验
    form = SmsLoginForm(data=request.POST)
    if not form.is_valid():
        res.status = False
        res.detail = form.errors
        return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})

    # 2. 对验证码格式的校验
    role = form.cleaned_data.get('role')
    mobile = form.cleaned_data.get('mobile')
    # conn = get_redis_connection()
    # cache_code = conn.get(mobile)  # 字节类型需转换为字符串
    # if not cache_code:
    #     res.status = False
    #     res.detail = {'code': ['验证码已过期']}
    #     return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})
    #
    # if code != cache_code.decode('utf-8'):
    #     res.status = False
    #     res.detail = {'code': ['验证码不正确']}
    #     return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})
    if role == '1':
        user_project = models.Administrator.objects.filter(active=1, mobile=mobile).first()
    else:
        user_project = models.Customer.objects.filter(active=1, mobile=mobile).first()

    #  检测手机号是否存在
    if not user_project:
        res.status = False
        res.detail = {'mobile': ['手机号不存在']}
        return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})

    # 用户信息写入session
    mapping = {'1': 'ADMIN', '2': 'CUSTOMER'}
    request.session[settings.NB_SESSION_KEY] = {'role': mapping[role], 'username': user_project.username,
                                                'id': user_project.id}
    res.status = True
    res.data = settings.LOGIN_HOME
    return JsonResponse(res.dict)


def sms_send(request):
    # 用对象的封装来减少语句的重复
    res = BaseResponse()

    # 1. 验证手机号的格式
    form = MobileForm(data=request.POST)
    if not form.is_valid():
        res.detail = form.errors
        return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})

    # 从数据库中检测数据是否存在
    role = request.POST.get('role')
    mobile = request.POST.get('mobile')
    if role == Role.ADMIN:
        exists = models.Administrator.objects.filter(active=1, mobile=mobile).exists()
    else:
        exists = models.Customer.objects.filter(active=1, mobile=mobile).exists()
    if not exists:
        res.status = False
        res.detail = {'mobile': ['手机号不存在']}
        return JsonResponse(res.dict, json_dumps_params={'ensure_ascii': False})

    # 2. 发送短信 + 生成验证码
    sms_code = randint(1000, 9999)
    print('验证码：', sms_code)

    # 3. 用redis将手机和验证码保存（以便于下次校验）
    conn = get_redis_connection('default')
    conn.set(mobile, sms_code, ex=60)  # 设置过期时间为60秒
    res.status = True
    return JsonResponse(res.dict)


def home(request):
    return render(request, 'home.html')
